<template>
  <div class="file-preview flex-box" v-resize="setImgSize">
    <!-- 空内容 -->
    <div
      v-if="!path"
      class="invalid"
      :title="path"
    >
      无效
    </div>
    <!-- 图片 -->
    <img
      v-else-if="!isExternal && isImage"
      class="img"
      :alt="path"
      :title="path"
      :src="url"
    >
    <!-- 外部图片 -->
    <img
      v-else-if="isExternal && isImage"
      class="img"
      :alt="path"
      :title="path"
      :src="url"
    >
    <!-- office文件 -->
    <div 
      v-else-if="isOffice" 
      class="filename" 
      :title="origin_filename"
    >
      {{ origin_filename }}
    </div>
    <!-- audio文件 -->
    <div 
      v-else-if="isAudio" 
      class="filename" 
      :title="origin_filename"
    >
      {{ origin_filename }}
    </div>
    <!-- zip文件 -->
    <div 
      v-else-if="isZip" 
      class="filename" 
      :title="origin_filename"
    >
      {{ origin_filename }}
    </div>
    <!-- text文件 -->
    <div 
      v-else-if="isText" 
      class="filename" 
      :title="origin_filename"
    >
      {{ origin_filename }}
    </div>
    <!-- 其他文件 -->
    <div 
      v-else 
      class="filename" 
      :title="origin_filename"
    >
      {{ origin_filename }}
    </div>
    <div class="actions flex-box">
      <space size="4">
        <template>
          <!-- 图片 -->
          <a-icon
            v-if="!isExternal && isImage"
            type="eye"
            @click.stop="onPreview"
            title="查看图片"
          />
          <!-- 外部图片 -->
          <a
            v-else-if="isExternal && isImage"
            type="eye"
            @click.stop="onPreview"
            title="查看外部图片"
          >
            <a-icon type="eye"/>
          </a>
          <!-- office文件 -->
          <a
            v-else-if="isOffice"
            :href="`http://view.officeapps.live.com/op/view.aspx?src=${path}`"
            target="_blank"
            title="查看office文件"
          >
            <a-icon type="eye"/>
          </a>
          <!-- audio文件 -->
          <a
            v-else-if="isAudio"
            :href="`${path}`"
            target="_blank"
            title="播放audio文件"
          >
            <a-icon type="play-circle"/>
          </a>
          <!-- zip文件 -->
          <a
            v-else-if="isZip"
            :href="`${path}`"
            target="_blank"
            title="下载zip文件"
          >
            <a-icon type="download"/>
          </a>
          <!-- text文件 -->
          <a-icon
            v-else-if="isText"
            type="eye"
            @click.stop="onPreview"
            title="查看text文件"
          />
          <!-- 其他文件 -->
          <a
            v-else
            :href="`${path}`"
            target="_blank"
            title="查看"
          >
            <a-icon type="eye"/>
          </a>
        </template>
        <slot v-if="!disabled" :file="formattedFile"/>
      </space>
    </div>
    <div class="annotation flex-box">
      <space>{{ origin_fileDesensitization }}</space>
    </div>
  </div>
</template>

<script>
import { isImage,isOffice,isExternal,isAudio,isZip,isText } from '@/libs/validates'
import { mapState } from 'vuex'
import { getUrl,getFilename,fileDesensitization } from '@/libs/utils'
import GlobalModal from '@c/GlobalModal'
import Space from '@c/Space'
import {getText} from '@/api/common'

export default {
  name: 'FilePreview',
  components: {
    Space,
  },
  data() {
    return {
      formattedFile: {
        path: '',
        url: '',
        filename: '',
        origin_filename: '',
      },
      width: 0,
      height: 0,
      content: '',
      visible: false
    }
  },
  props: {
    file: null,
    /**
     * 是否禁用
     */
    disabled: {
      type: Boolean,
      default: false,
    },
    ...mapState(['miniWidth']),
  },
  computed: {
    isImage() {
      return isImage(this.formattedFile.path)
    },
    isOffice() {
      return isOffice(this.formattedFile.path)
    },
    isAudio() {
      return isAudio(this.formattedFile.path)
    },
    isExternal() {
      return isExternal(this.formattedFile.path)
    },
    isZip() {
      return isZip(this.formattedFile.path)
    },
    isText() {
      return isText(this.formattedFile.path)
    },
    url() {
      return this.formattedFile.url
    },
    path() {
      return this.formattedFile.path
    },
    filename() {
      return this.formattedFile.filename
    },
    origin_filename() {
      return this.formattedFile.origin_filename;
    },
    origin_fileDesensitization() {
      return fileDesensitization(this.formattedFile.origin_filename);
    },
  },
  methods: {
    onload(file){
      return new Promise(resolve => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => {
          const img = document.createElement('img');
          img.src = reader.result;
          img.onload = () => {
            const canvas = document.createElement('canvas');
            canvas.width = img.naturalWidth;
            canvas.height = img.naturalHeight;
            const ctx = canvas.getContext('2d');
            ctx.drawImage(img, 0, 0);
            ctx.fillStyle = 'red';
            ctx.textBaseline = 'middle';
            ctx.font = '33px Arial';
            ctx.fillText('Ant Design Vue', 20, 20);
            canvas.toBlob(resolve);
          };
        };
      });
    },
    toUpperCase(str) {
      return str.toUpperCase()
    },
    /**
     * 把传入的 file 值，格式化为一个有几个必要字段（path, url）的对象
     */
    formatFile() {
      const f = this.file
      if (!f) {
        return
      }

      if (typeof f === 'string') {
        this.formattedFile = {
          path: f,
          url: getUrl(f),
          filename: getFilename(f),
        }
      } else if (typeof f === 'object') {
        this.formattedFile = Object.assign({}, f, {
          path: f.path || '',
          url: f.url || getUrl(f.path),
          filename: f.filename || getFilename(f.path),
        })
      }
    },
    onPreview() {
      if (this.isImage && this.isExternal) {
        this.setImgSize()
        GlobalModal.new({
          propsData: {
            wrapClassName: 'img-preview-dialog',
            width: 'auto',
            content: (h) => {
              return (
                <img
                  src={this.formattedFile.url}
                  width={this.width}
                  height={this.height}
                />
              )
            },
          },
        })
      } else if (this.isImage && !this.isExternal) {
        this.setImgSize()
        GlobalModal.new({
          propsData: {
            wrapClassName: 'img-preview-dialog',
            width: 'auto',
            content: (h) => {
              return (
                <img
                  src={this.formattedFile.url}
                  width={this.width}
                  height={this.height}
                />
              )
            },
          },
        })
      } else if (this.isText) {
        getText(this.formattedFile.url).then(res=>{
          this.content = res;
        })
        GlobalModal.new({
          propsData: {
            width: '400px',
            content: (h) => {
              return (<pre>{this.content}</pre>)
            },
          },
        })
      }
    },
    setImgSize() {
      if (!this.isImage) {
        return
      }

      const maxWidth = Math.min(1000, window.innerWidth * 0.9)
      const maxHeight = window.innerHeight * 0.9

      const imgEl = this.$el.querySelector('.img')
      this.width = imgEl.naturalWidth || 1
      this.height = imgEl.naturalHeight || 1
      const ratio = this.width / this.height

      if (this.width > maxWidth) {
        this.width = maxWidth
        this.height = this.width / ratio
      }

      if (this.height > maxHeight) {
        this.height = maxHeight
        this.width = this.height * ratio
      }
    },
    showModal() {
      this.visible = true;
    },
    handleOk() {
      this.visible = false;
    },
  },
  watch: {
    file: {
      handler() {
        this.formatFile()
      },
      immediate: true,
    },
  },
}
</script>

<style scoped lang="less">
@import "~@/styles/vars";

.file-preview {
  width: 100px;
  height: 100px;
  min-width: 100px;
  min-height: 100px;
  overflow: hidden;
  border: @border-base;
  border-radius: 4px;
  margin: 0 5px 5px 0;
  transition: all .3s;
  position: relative;

  &:hover {
    .actions {
      opacity: 1;
    }
    .annotation {
      opacity: 1;
    }
  }

  img {
    max-width: 100%;
    max-height: 100%;
    word-break: break-all;
  }

  .path {
    overflow: hidden;
    margin: 0 5px;
    font-size: 12px;
    word-break: break-all;
    line-height: normal;
  }

  .filename {
    overflow: hidden;
    margin: 0 5px;
    font-size: 12px;
    word-break: break-all;
    line-height: normal;
  }

  .invalid {
    font-size: 20px;
    font-style: italic;
  }
}

.annotation {
  width: 100%;
  height: 20%;
  position: absolute;
  left: 0;
  bottom: 0;
  opacity: 0;
  background: rgba(0, 0, 0, 0.6);

  > * {
    font-size: 12px;
    cursor: pointer;
    text-decoration: none;
    color: #f9f2f4;
  }
}

.actions {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
  background: rgba(0, 0, 0, 0.6);
  transition: all .3s;

  > * {
    font-size: 24px;
    cursor: pointer;
    text-decoration: none;
    color: @blue-6;
  }
}
</style>

<style lang="less">
.img-preview-dialog {
  display: flex;
  align-items: center;
  justify-content: center;

  .ant-modal {
    width: auto;
    display: inline-block;
    top: auto;
    padding: 0;
  }

  .ant-modal-body {
    padding: 0;
    border-radius: 4px;
  }

  img {
    border-radius: 4px;
  }
}
</style>
